home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / mac / source / dialgmgr.sit / Dialogs ƒ / PopUpMenu.p < prev    next >
Text File  |  1989-12-27  |  6KB  |  229 lines

  1. Unit TPopUpMenu;
  2.  
  3. {        ⌐1986-1989            Bill Stackhouse                                    }
  4. {                                Stackhouse Software                                }
  5. {                                Natick, MA 01760                                    }
  6.  
  7. Interface
  8.  
  9. {$IFC UNDEFINED UsePopUpMenu}
  10. {$SETC UsePopUpMenu = FALSE}
  11. {$ENDC}
  12. {$IFC UsePopUpMenu}
  13.  
  14.     Uses
  15.         TObject;
  16.  
  17.     Const
  18.         maxPopUps = 15;
  19.  
  20.     Type
  21.         TPopUpMenu = Object(TObject)
  22.                 numPopGroups: 0..maxPopUps;                {number of popup menus}
  23.                 callBackProc: ProcPtr;                        {who to call back after menu used}
  24.                 PopGroup: Array[1..maxPopUps] Of Record
  25.                         menu: MenuHandle;                        {handle to menu}
  26.                         resNum: Integer;                            {resource number of menu}
  27.                         static: Integer;                            {item number of related static text}
  28.                         nowOn: Integer;                            {which item in menu is current}
  29.                         popUpBox: Rect;                            {rectangle for popup box, computed}
  30.                         promptBox: Rect;                            {static text box outline}
  31.                         itemText: Str255;                        {text of current item}
  32.                     End;
  33.                 Procedure TPopUpMenu.Init;
  34.                 Procedure TPopUpMenu.Add (pMenu: MenuHandle;    {}
  35.                                             pMenuRes: Integer;                        {}
  36.                                             pStatic: Integer;                            {}
  37.                                             pNowOn: Integer);                            {}
  38.                 Procedure TPopUpMenu.Revise (curDialog: DialogPtr);
  39.                 Procedure TPopUpMenu.Draw (i: Integer);
  40.                 Procedure TPopUpMenu.DrawAll;
  41.                 Procedure TPopUpMenu.Mouse (theEvent: EventRecord);
  42.                 Procedure TPopUpMenu.Get (theGroup: Integer;
  43.                                             Var theItem: Integer;
  44.                                             Var theText: Str255);
  45.                 Function TPopUpMenu.Error: Integer;
  46.                 Procedure TPopUpMenu.CallBack (theCallBack: ProcPtr);
  47.             End;
  48.  
  49. {$ENDC}
  50.  
  51. Implementation
  52.  
  53. {$IFC UsePopUpMenu}
  54.  
  55.     Const
  56.         DialogGroupIgnored = -10;    {too many groups, key, menus, or user items were added}
  57.  
  58.     Var
  59.         globalError: Integer;
  60.  
  61.     Procedure UserAction (proc: ProcPtr);
  62.     Inline
  63.         $205f,     {movea.l  (a7)+,a0        ; (a0) is a ptr to string, 4(a0) is mode}
  64.         $4e90;
  65.  
  66.     Procedure TPopUpMenu.Init;
  67.     Begin
  68.         globalError := noErr;
  69.         SELF.numPopGroups := 0;
  70.         SELF.callBackProc := Nil;
  71.     End;        {TPopUpMenu.Init}
  72.  
  73.     Procedure TPopUpMenu.Add (pMenu: MenuHandle;    {}
  74.                                     pMenuRes: Integer;                        {}
  75.                                     pStatic: Integer;                            {}
  76.                                     pNowOn: Integer);                            {}
  77.         Var
  78.             i: Integer;
  79.     Begin
  80.         globalError := noErr;
  81.         With SELF Do
  82.             If numPopGroups < maxPopUps Then
  83.             Begin
  84.                 numPopGroups := numPopGroups + 1;
  85.                 With PopGroup[numPopGroups] Do
  86.                 Begin
  87.                     menu := pMenu;
  88.                     resNum := pMenuRes;
  89.                     static := pStatic;
  90.                     nowOn := pNowOn;
  91.                     SetRect(popUpBox, 0, 0, 0, 0);
  92.                     SetRect(promptBox, 0, 0, 0, 0);
  93.                     If menu = Nil Then
  94.                         menu := GetMenu(resNum);
  95.                     For i := 1 To CountMItems(menu) Do
  96.                         SetItemMark(menu, i, ' ');
  97.                     SetItemMark(menu, nowOn, CHR(checkMark));
  98.                 End;
  99.             End
  100.             Else
  101.                 globalError := DialogGroupIgnored;
  102.     End;        {TPopUpMenu.Add}
  103.  
  104.     Procedure TPopUpMenu.Draw;
  105.         Const
  106.             leftSlop = 13;            {leave this much space on left of title}
  107.             botSlop = 5;                {this much below baseline}
  108.     Begin
  109.         globalError := noErr;
  110.         With SELF.popGroup[i] Do
  111.         Begin
  112.             EraseRect(popUpBox);
  113.             With promptBox Do
  114.                 SetRect(popUpBox, right + 1, top, right + menu^^.menuWidth + 1, bottom + 2);    {l,t,r,b}
  115.             FrameRect(popUpBox);
  116.             With popUpBox Do
  117.             Begin
  118.                 MoveTo(right, top + 2);
  119.                 LineTo(right, bottom);
  120.                 LineTo(left + 2, bottom);
  121.                 MoveTo(left + LeftSlop, bottom - BotSlop);
  122.                 GetItem(menu, nowOn, itemText);
  123.                 DrawString(itemText);
  124.             End;
  125.         End;
  126.     End;        {TPopUpMenu.Draw}
  127.  
  128.     Procedure TPopUpMenu.DrawAll;
  129.         Var
  130.             i: Integer;
  131.     Begin
  132.         globalError := noErr;
  133.         For i := 1 To SELF.numPopGroups Do
  134.             SELF.Draw(i);
  135.     End;        {TPopUpMenu.DrawAll}
  136.  
  137.     Procedure TPopUpMenu.Revise (curDialog: DialogPtr);
  138.         Var
  139.             i: Integer;
  140.             curFont, curFontSize: Integer;
  141.             fontData: FontInfo;
  142.             theType: Integer;
  143.             theHandle: Handle;
  144.             theBox: Rect;
  145.     Begin
  146.         globalError := noErr;
  147.         With SELF Do
  148.             For i := 1 To numPopGroups Do
  149.                 With popGroup[i] Do
  150.                 Begin
  151.                     curFont := thePort^.txFont;
  152.                     curFontSize := thePort^.txSize;
  153.                     TextFont(SystemFont);
  154.                     TextSize(12);
  155.                     GetFontInfo(fontData);
  156.                     TextFont(curFont);
  157.                     TextSize(curFontSize);
  158.                     GetDItem(curDialog, static, theType, theHandle, promptBox);
  159.                     With promptBox, fontData Do
  160.                         SetRect(promptBox, left, top, right, top + ascent + descent + leading);    {l,t,r,b}
  161.                     SetDItem(curDialog, static, theType, theHandle, promptBox);
  162.                 End;
  163.     End;        {TPopUpMenu.Revise}
  164.  
  165.     Procedure TPopUpMenu.Mouse (theEvent: EventRecord);
  166.         Var
  167.             i: Integer;
  168.             popLoc: Point;
  169.             chosen: Longint;
  170.             newChoice: Integer;
  171.     Begin
  172.         globalError := noErr;
  173.         GlobalToLocal(theEvent.where);                            {because PtInRect wants it that way}
  174.         With theEvent, SELF Do
  175.         Begin
  176.             If numPopGroups > 0 Then
  177.                 For i := 1 To numPopGroups Do
  178.                     If PtInRect(theEvent.where, PopGroup[i].popUpBox) Then
  179.                         With PopGroup[i] Do
  180.                         Begin
  181.                             InvertRect(promptBox);            {hilight the prompt}
  182.                             InsertMenu(menu, -1);                {insert our menu in the menu list}
  183.                             popLoc := popUpBox.topLeft;        {copy our item╒s topleft}
  184.                             LocalToGlobal(popLoc);                {convert back to global coords}
  185.                             CalcMenuSize(menu);                {Work around Menu Mgr bug}
  186.                             With popLoc Do
  187.                                 chosen := PopUpMenuSelect(menu, v, h, nowOn);
  188.                             InvertRect(promptBox);            {unhilight the prompt}
  189.                             DeleteMenu(resNum);                {remove our menu from the menu list}
  190.                             If chosen <> 0 Then
  191.                             Begin
  192.                                 newChoice := LoWord(chosen);        {get the chosen item number}
  193.                                 If newChoice <> nowOn Then
  194.                                 Begin
  195.                                     SetItemMark(menu, nowOn, ' ');                            {unmark the old choice}
  196.                                     SetItemMark(menu, newChoice, CHR(checkMark));        {mark the new choice}
  197.                                     nowOn := newChoice;                                        {update the current choice}
  198.                                     SELF.Draw(i);
  199.                                     If callBackProc <> Nil Then
  200.                                         UserAction(callBackProc);        {let them play around}
  201.                                 End;
  202.                                 Leave;
  203.                             End;    {With}
  204.                         End;
  205.         End;
  206.     End;        {TPopUpMenu.Mouse}
  207.  
  208.     Procedure TPopUpMenu.Get (theGroup: Integer;
  209.                                     Var theItem: Integer;
  210.                                     Var theText: Str255);
  211.     Begin
  212.         globalError := noErr;
  213.         theItem := SELF.PopGroup[theGroup].nowOn;
  214.         theText := SELF.PopGroup[theGroup].itemText;
  215.     End;        {TPopUpMenu.GetNowOn}
  216.  
  217.     Function TPopUpMenu.Error: Integer;
  218.     Begin
  219.         Error := globalError;
  220.     End;        {TPopUpMenu.Error}
  221.  
  222.     Procedure TPopUpMenu.CallBack (theCallBack: ProcPtr);
  223.     Begin
  224.         SELF.callBackProc := theCallBack;
  225.     End;        {TPopUpMenu.CallBack}
  226.  
  227. {$ENDC}
  228.  
  229. End.